package com.aryankh.wordbookfx.controller;

import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.alimt20181012.models.TranslateGeneralResponse;
import com.aryankh.wordbookfx.WordBookFxApplication;
import com.aryankh.wordbookfx.constant.PathConstants;
import com.aryankh.wordbookfx.constant.ThemeColorConstants;
import com.aryankh.wordbookfx.constant.TranslateRequestConstants;
import com.aryankh.wordbookfx.entity.AccessKeyEntity;
import com.aryankh.wordbookfx.service.WordService;
import com.aryankh.wordbookfx.util.AudioUtil;
import com.aryankh.wordbookfx.util.CharacterUtil;
import com.aryankh.wordbookfx.util.SimpleTranslateRequest;
import com.aryankh.wordbookfx.util.wy.AuthV3Util;
import com.aryankh.wordbookfx.util.wy.HttpUtil;
import com.aryankh.wordbookfx.view.WordBookMainView;
import de.felixroske.jfxsupport.FXMLController;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.paint.Paint;
import javafx.scene.text.Text;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * @Author AryanKH
 * @Date 2023/4/27 18:14
 */
@FXMLController
public class TranslateController implements Initializable {

    @FXML
    private Button readBtn;

    @FXML
    private ToolBar mainBar;

    @FXML
    private AnchorPane mainBroad;

    @FXML
    private ToggleButton langToggle;
    static AccessKeyEntity accessKeyEntity = new AccessKeyEntity();
    @FXML
    private Button resetBtn;

    @FXML
    private TextArea textAreaBox;

    @FXML
    private TextField accessKeySecretBox;

    @FXML
    private TextField accessKeyIdBox;

    @FXML
    private Button checkBtn;

    @FXML
    private Button translateBtn;

    @FXML
    private TextField inputBox;

    @FXML
    private Text testInternet;

    String selectedItem = "Aliyun";
    @FXML
    private ChoiceBox<String> translatorDropList;

    @FXML
    private Button backBtn;

    String sourceLanguage = TranslateRequestConstants.CHINESE;
    String targetLanguage = TranslateRequestConstants.ENGLISH;
    static FileWriter fileWriter;
    static FileReader fileReader;

    String resCollect = "";

    String phonicUrl = "";

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        initTableDropList();
        try {
            isConnected();
            fileReader = new FileReader(PathConstants.ACCESS_KEY_PATH);
            if (fileReader.getFile().exists()) {
                reloadAccessKeyFile();
            }
            if (accessKeySecretBox.getText().isEmpty() || accessKeySecretBox.getText().isEmpty()) {
                resetBtn.setDisable(true);
            } else {
                resetBtn.setDisable(false);
            }
        } catch (IORuntimeException e) {
            List<String> initContent = new ArrayList<>();
            initContent.add("ACCESS_KEY_ID");
            initContent.add("ACCESS_KEY_SECRET");
            fileWriter = new FileWriter(PathConstants.ACCESS_KEY_PATH);
            fileWriter.writeLines(initContent);
        }
        reloadTheme();
    }

    private void reloadTheme() {
        FileReader fileReader = new FileReader(PathConstants.C_THEME_NAME);
        if ("LightMode".equals(fileReader.readString())) {
            lightMod();
        } else if ("DarkMode".equals(fileReader.readString())) {
            darkMod();
        }
    }

    private void darkMod() {
        mainBroad.setBackground(new Background(new BackgroundFill(Paint
                .valueOf(ThemeColorConstants.PURPLISH_BLACK), null, null)));

        backBtn.setBackground(new Background(new BackgroundFill(Paint
                .valueOf(ThemeColorConstants.PURPLISH_BLACK), null, null)));
        backBtn.setTextFill(Paint.valueOf(ThemeColorConstants.GRAY_WHITE));

        checkBtn.setBackground(new Background(new BackgroundFill(Paint
                .valueOf(ThemeColorConstants.PURPLISH_BLACK), null, null)));
        checkBtn.setTextFill(Paint.valueOf(ThemeColorConstants.GRAY_WHITE));

        resetBtn.setBackground(new Background(new BackgroundFill(Paint
                .valueOf(ThemeColorConstants.PURPLISH_BLACK), null, null)));
        resetBtn.setTextFill(Paint.valueOf(ThemeColorConstants.GRAY_WHITE));

        mainBar.setBackground(new Background(new BackgroundFill(Paint
                .valueOf(ThemeColorConstants.MODENA_PURPLE), null, null)));
        testInternet.setFill(Paint.valueOf(ThemeColorConstants.GRAY_WHITE));

        textAreaBox.setStyle("-fx-text-fill:#414450; ");


        inputBox.setBackground(new Background(
                new BackgroundFill(Paint.valueOf(ThemeColorConstants.MODENA_PURPLE), null, null)));
        inputBox.setStyle("-fx-text-fill:#CED0D6;");

        langToggle.setBackground(new Background(
                new BackgroundFill(Paint.valueOf(ThemeColorConstants.MODENA_PURPLE), null, null)));
        langToggle.setStyle("-fx-text-fill:#CED0D6;");

        readBtn.setBackground(new Background(
                new BackgroundFill(Paint.valueOf(ThemeColorConstants.MODENA_PURPLE), null, null)));
        readBtn.setStyle("-fx-text-fill:#CED0D6;");

        translateBtn.setBackground(new Background(
                new BackgroundFill(Paint.valueOf(ThemeColorConstants.MODENA_PURPLE), null, null)));

        translateBtn.setStyle("-fx-text-fill:#CED0D6;");

        accessKeyIdBox.setBackground(new Background(
                new BackgroundFill(Paint.valueOf(ThemeColorConstants.MODENA_PURPLE), null, null)));

        accessKeyIdBox.setStyle("-fx-text-fill:#CED0D6;");

        accessKeySecretBox.setBackground(new Background(
                new BackgroundFill(Paint.valueOf(ThemeColorConstants.MODENA_PURPLE), null, null)));
        accessKeySecretBox.setStyle("-fx-text-fill:#CED0D6;");
    }

    private void lightMod() {


    }


    @FXML
    void onRead(MouseEvent event) {
        new Thread(() -> {
            AudioUtil audioUtil = new AudioUtil();
            try {
                audioUtil.downloadAudio(phonicUrl, PathConstants.AUDIO_PATH);
                Media media = new Media(new File(PathConstants.AUDIO_PATH).toURI().toString());
                MediaPlayer mediaPlayer = new MediaPlayer(media);
                mediaPlayer.play();
            } catch (IOException e) {
                textAreaBox.setText("请检查是否按下 \"Translate\" 按钮");
            }

        }).start();
    }

    private boolean testInternet() {
        final URL url;
        final URLConnection conn;
        try {
            url = new URL("https://www.aliyun.com/");
            conn = url.openConnection();
            conn.connect();
            conn.getInputStream().close();
            return true;
        } catch (IOException e) {
            return false;
        }

    }

    private void initTableDropList() {
        // 初始化dropList
        translatorDropList.getItems().add("Youdao");
        translatorDropList.getItems().add("Aliyun");
        translatorDropList.getSelectionModel().select(0);
        selectedItem = translatorDropList.getSelectionModel().getSelectedItem();

        // 初始化dropList监听
        translatorDropList.getSelectionModel().selectedItemProperty()
                .addListener((observable, oldValue, newValue) -> {
                    selectedItem = translatorDropList.getSelectionModel().getSelectedItem();
                });
    }

    @FXML
    void onTest(MouseEvent event) {
        isConnected();
    }


    @FXML
    void onCheck(MouseEvent event) {
        if (accessKeySecretBox.getText().isEmpty() && accessKeySecretBox.getText().isEmpty()) {
            textAreaBox.setPromptText("accessKeySecretBox or accessKeySecretBox is empty");
        } else {
            textAreaBox.setPromptText("");
            accessKeyEntity.setAccessKeyId(accessKeyIdBox.getText());
            accessKeyEntity.setAccessKeySecret(accessKeySecretBox.getText());
            checkBtn.setDisable(true);
            accessKeyIdBox.setDisable(true);
            accessKeySecretBox.setDisable(true);
            saveAccessKey(accessKeyEntity);
            resetBtn.setDisable(false);
        }
    }

    @FXML
    void onReset(MouseEvent event) {
        checkBtn.setDisable(false);
        accessKeyIdBox.setDisable(false);
        accessKeyIdBox.setText("");
        accessKeySecretBox.setDisable(false);
        accessKeySecretBox.setText("");
        accessKeyEntity.setAccessKeySecret("");
        accessKeyEntity.setAccessKeyId("");
        resetBtn.setDisable(true);
    }

    @FXML
    void onToggleClicked(MouseEvent event) {
        if (langToggle.isSelected()) {
            langToggle.setText("TargetLanguage -> English");
            sourceLanguage = TranslateRequestConstants.ENGLISH;
            targetLanguage = TranslateRequestConstants.CHINESE;
        } else {
            langToggle.setText("TargetLanguage -> Chinese");
            sourceLanguage = TranslateRequestConstants.CHINESE;
            targetLanguage = TranslateRequestConstants.ENGLISH;
        }
    }

    @FXML
    void onTranslate(MouseEvent event) {
        String sourceText = inputBox.getText();
        if ("Aliyun".equals(selectedItem)) {
            textAreaBox.setText(translateRequest(accessKeyEntity, targetLanguage, sourceLanguage, sourceText));
        } else if ("Youdao".equals(selectedItem)) {
            youdaoTranslateRequest(accessKeyEntity,
                    targetLanguage, sourceLanguage, sourceText);
        }

    }

    /**
     * need to update!
     *
     * @param event
     * @author AryanKH
     * @date 2023/6/9 22:31
     */

    @FXML
    void onBack(MouseEvent event) {
        WordBookFxApplication.showView(WordBookMainView.class);
    }

    private void reloadAccessKeyFile() {
        FileReader fileReader = new FileReader(PathConstants.ACCESS_KEY_PATH, "UTF-8");
        List<String> accessKeys = fileReader.readLines();
        accessKeyIdBox.setText(accessKeys.get(0));
        accessKeySecretBox.setText(accessKeys.get(1));
        accessKeyEntity.setAccessKeyId(accessKeys.get(0));
        accessKeyEntity.setAccessKeySecret(accessKeys.get(1));
        checkBtn.setDisable(true);
        accessKeyIdBox.setDisable(true);
        accessKeySecretBox.setDisable(true);

    }

    private void saveAccessKey(AccessKeyEntity accessKeyEntity) {
        FileWriter fileWriter = new FileWriter(PathConstants.ACCESS_KEY_PATH);
        List<String> accessKeyEntities = new ArrayList<>();
        accessKeyEntities.add(accessKeyEntity.getAccessKeyId());
        accessKeyEntities.add(accessKeyEntity.getAccessKeySecret());
        fileWriter.writeLines(accessKeyEntities);
    }

    private void isConnected() {
        new Thread(() -> {
            if (testInternet()) {
                testInternet.setText("成功接入互联网!");
                if (translateBtn.isDisable() || textAreaBox.isDisable()) {
                    translateBtn.setDisable(false);
                }
            } else {
                testInternet.setText("已断开互联网连接!");
                translateBtn.setDisable(true);
            }
        }).start();
    }

    /**
     * 阿里翻译api
     *
     * @param accessKeyEntity
     * @param targetLanguage
     * @param sourceLanguage
     * @param sourceText
     * @return String
     * @author AryanKH
     * @date 2023/6/9 21:24
     */

    private String translateRequest(AccessKeyEntity accessKeyEntity,
                                    String targetLanguage, String sourceLanguage,
                                    String sourceText) {
        try {
            TranslateGeneralResponse result = null;
            try {
                result = SimpleTranslateRequest.sendRequest(accessKeyEntity, TranslateRequestConstants.FORMAT_TYPE,
                        targetLanguage, sourceLanguage,
                        sourceText,
                        TranslateRequestConstants.SCENE);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            assert result != null;
            return result.getBody().getData().getTranslated();
        } catch (RuntimeException e) {
            return "ACCESS_KEY_SET_ERROR";
        }
    }

    /**
     * 有道 api
     *
     * @return Map<String [ ]>
     * @author AryanKH
     * @date 2023/6/9 21:24
     */
    private static Map<String, String[]> createRequestParams(String targetLanguage,
                                                             String sourceLanguage,
                                                             String sourceText) {
        /*
         * note: 将下列变量替换为需要请求的参数
         */
        String from;
        String to;
        //  String query = "这是一个句子";
        if (!"zh".equals(targetLanguage)) {
            from = "en";
            to = "zh-CHS";
        } else {
            from = "zh-CHS";
            to = "en";
        }

        String vocabId = "您的用户词表ID";

        return new HashMap<String, String[]>(128) {{
            put("q", new String[]{new String(sourceText.getBytes(), StandardCharsets.UTF_8)});
            put("from", new String[]{from});
            put("to", new String[]{to});
            put("vocabId", new String[]{vocabId});
        }};
    }

    private void youdaoTranslateRequest(AccessKeyEntity accessKeyEntity,
                                        String targetLanguage,
                                        String sourceLanguage,
                                        String sourceText) {
        // 添加请求参
        Map<String, String[]> params = createRequestParams(targetLanguage, sourceLanguage,
                sourceText);
        // 添加鉴权相关参数
        try {
            AuthV3Util.addAuthParams(accessKeyEntity.getAccessKeyId(),
                    accessKeyEntity.getAccessKeySecret(), params);
            // 请求api服务
            byte[] result = HttpUtil.doPost("https://openapi.youdao.com/api", null,
                    params, "application/json");
            // 打印返回结果
            if (result != null) {
                String s = new String(result, StandardCharsets.UTF_8);
                JSONObject jsonObject = JSON.parseObject(s);
                phonicUrl = jsonObject.getString("speakUrl");
                if (CharacterUtil.isChinese(sourceText)) {
                    // 处理中文
                    try {
                        resCollect = "";
                        try {
                            JSONObject basic = jsonObject.getJSONObject("basic");
                            JSONArray explains = basic.getJSONArray("explains");
                            phonicUrl = jsonObject.getString("tSpeakUrl");
                            explains.forEach(res -> resCollect += res.toString() + "\n");
                            textAreaBox.setText(resCollect);
                        } catch (NullPointerException e) {
                            JSONArray translation = jsonObject.getJSONArray("translation");
                            phonicUrl = jsonObject.getString("tSpeakUrl");
                            translation.forEach(res -> resCollect += res.toString() + "\n");
                            textAreaBox.setText(resCollect);
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                        //textAreaBox.setText("Oops! Something is go wrong");
                    }
                } else {
                    if (sourceText.contains(" ")) {
                        // 处理 enPhrase/sentence -> zh
                        try {
                            resCollect = "";
                            JSONArray translation = jsonObject.getJSONArray("translation");
                            resCollect += translation.get(0).toString();
                            textAreaBox.setText(resCollect);
                        } catch (Exception e) {
                            textAreaBox.setText("Check your phrase or sentence spelling");
                        }
                    } else {
                        // 处理英译汉
                        try {
                            resCollect = "";
                            JSONObject basic = jsonObject.getJSONObject("basic");
                            resCollect += "DJ-PA: /" + basic.getString("uk-phonetic") + "/" + "\n";
                            JSONArray explains = basic.getJSONArray("explains");
                            explains.forEach(res -> resCollect += res.toString() + "\n");
                            textAreaBox.setText(resCollect);
                        } catch (Exception e) {
                            textAreaBox.setText("Check your word spelling");
                        }
                    }
                }
            }
        } catch (NoSuchAlgorithmException e) {
            //  acquisition
            textAreaBox.setText("目标语言匹配失败");
        }
    }
}
